﻿using System.IO;
using AnimationPackerEngine;
using AnimationPackerEngine.Exporters;

namespace AnimatedSpritePacker.XnaExporters.IndexExporters
{
    public class CSharpAtlasIndexExporter : IAtlasIndexExporter
    {
        private class CountingIndex
        {
            private int index = 0;

            internal int Index
            {
                get
                {
                    return index++;
                }
            }
        };

        #region IAtlasIndexExporter Members
        public string IndexExtension
        {
            get { return "cs"; }
        }

        public void Save(string filename, ProcessingAnimationCollection animationCollection)
        {
            CountingIndex frameCounter = new CountingIndex();
            CountingIndex scriptCounter = new CountingIndex();
            string outputNamespace = Clean(Path.GetFileNameWithoutExtension(filename));

            using (TextWriter writer = File.CreateText(filename))
            {
                writer.WriteLine("// TOOL-GENERATED FILE! YOUR EDITS MAY (WILL!) BE OVERWRITTEN!");
                writer.WriteLine();
                writer.WriteLine(string.Format("namespace {0}", outputNamespace));
                writer.WriteLine("{");
                writer.WriteLine("   namespace SpriteFrames");
                writer.Write("   {");

                foreach (var anim in animationCollection.AnimationCollection)
                {
                    writer.WriteLine();
                    writer.Write("      public static class ");
                    writer.Write(Clean(anim.Name));
                    writer.WriteLine();
                    writer.WriteLine("      {");

                    foreach (var frame in anim.Frames)
                    {
                        string name = Clean(frame.Filename);
                        if (name == Clean(anim.Name))
                        {
                            name += "Sprite";
                        }

                        writer.WriteLine(string.Format("         public const int {0} = {1};", name, frameCounter.Index));
                    }

                    writer.WriteLine("      }");
                }

                writer.WriteLine("   }");
                writer.WriteLine();
                writer.WriteLine("   namespace Animations");
                writer.Write("   {");

                foreach (var anim in animationCollection.AnimationCollection)
                {
                    writer.WriteLine();
                    writer.Write("      public static class ");
                    writer.Write(Clean(anim.Name));
                    writer.WriteLine();
                    writer.WriteLine("      {");

                    foreach (var script in anim.AnimationCompiler.Animations)
                    {
                        string name = Clean(script.Name);
                        if (name == Clean(anim.Name))
                        {
                            name += "Script";
                        }

                        writer.WriteLine(string.Format("         public const int {0} = {1};", name, scriptCounter.Index));
                    }

                    writer.WriteLine("      }");
                }

                writer.WriteLine("   }");
                writer.WriteLine("}");
            }
        }

        private string Clean(string entry)
        {
            string clean = entry.Substring(0, 1).ToUpper() + entry.Substring(1);

            //? is there a way to say "turn this string into a valid c# identifier"?
            return clean.Replace(' ', '_')
                        .Replace('-', '_')
                        .Replace('.', '_');
        }

        #endregion
    }
}
